
//题目的模型





/***
 * 选择约束类
 */
export class ChoiceCondition {

    _minSelectCount = 0;    //最小选择数目
    _maxSelectCount = 1;    //最大选择数目

    constructor(minSelectCount,maxSelectCount){
        this.minSelectCount = minSelectCount;
        this.maxSelectCount = maxSelectCount;
    }

    //获得最小选择数目
    get minSelectCount() {
        return this._minSelectCount;
    }

    //设置最小选择数目
    set minSelectCount(value) {
        if (value > this._maxSelectCount ){
            this._maxSelectCount = value;
        }

        this._minSelectCount = value;
    }


    //获得最大选择数目
    get maxSelectCount(){
        return this._maxSelectCount;
    }

    //设置最大选择数目
    set maxSelectCount(value){
        if (value < this._minSelectCount ){
            this._minSelectCount = value;
        }

        this._maxSelectCount = value;
    }



    //是否必须选择
    get requisite(){
        return this.minSelectCount > 0;
    }


    //是否多选
    get multiselect(){
        return this.maxSelectCount == 1;
    }


   

}





/***
 * 选择题
 */
export class ChoiceQuestion extends ChoiceCondition{



    type;   //题目类型
    id;     //题目的唯一标识符
    subject;    //问题
    options;    //所有的选项
    rightAnswers;    //正确答案
    originalData;   //原始数据

    score;
    

    get totalScore(){
        return this.testAnswer() ? this.score : 0;
    }




    constructor(subject,minSelectCount,maxSelectCount,id,type,originalData,options =[],rightAnswers = [],score = 1){
        super(minSelectCount,maxSelectCount);

        this.subject = subject;
        this.options = options;
        this.id = id;
        this.type = type;
        this.rightAnswers = rightAnswers;
        this.originalData = originalData;
        this.score = score;

    }

    deselect(){
        this.options.forEach(function(option){
            option.selected = false;
        });
    }

    // 获得默认选中的索引项
    get defaultSelectIndexs(){

        let defIndexs = [];
        let maxSelectCount = this.maxSelectCount;

        this.options.reduce(function(total,option,index) {
            if (option.default){

                if (total <= maxSelectCount){
                    defIndexs.push(index);
                }else {
                    option.default = false;
                }
            }
        },0);

        return defIndexs;
    }


    // 获得选择的选项
    get selectedOptions(){
        return this.options.filter(function(option,index){
            return option.selected;
        });
    }


    // 获得选择的选项的id
    get selectedIds(){
        return this.options.map(function(option,index){
            return option.selected ? option.id : null;
        });
    }



    //测试是否满足必须
    testRequisite(){
        return !(this.requisite) || this.selectedOptions.length > 0 ;
    }


    //测试是否满足最小选择数
    testMinSelectCount(){
        return this.selectedOptions.length >= this.minSelectCount;
    }

    //测试是否满足最大选择数
    testMaxSelectCount(){
        return this.selectedOptions.length <= this.maxSelectCount;
    }

    //测试是否满足所有的约束条件
    testAllCondition(){
        return this.testRequisite() && this.testMinSelectCount() && this.testMaxSelectCount();
    }


    //测试是否回答正确
    testAnswer(){

        let rightIDs = this.rightAnswers.map(function (answer) {
            return answer.id;
        });

        let selectedIDs = this.selectedOptions.map(function (option) {
            return option.id;
        });



        let selectedsIsAllRight = this.selectedIDs.every(function(seleId){

            let haveId = rightIDs.includes(seleId);

            rightIDs = rightIDs.filter(function(rightId){
                return rightId != seleId;
            });

            return haveId;
        });


        let rightIsAllSelected = rightIDs.length == 0;



        return selectedsIsAllRight && rightIsAllSelected;

    }


}


/***
 * 选项
 */
export class Option {
    id;     //选项的标识符，在一个题目中，需要唯一
    content;    //选项的内容
    choiceQuestion;     //选择所属的题目
    _default;       //是否默认选中
    selected;   //是否选中

    originalData;   //原始数据

    constructor(content,id,choiceQuestion,originalData,defaultSelected = false){
        this.content = content;
        this.id = id ;
        this.choiceQuestion = choiceQuestion;
        this.defaultSelected = this.defaultSelected;
        this.originalData = originalData;
    }

    //检查是否默认选中
    get defaultSelected(){
        return this._default;
    }

    //设置默认选中
    set defaultSelected(value){
        if (value){
            this.selected = true;
        }

        this._default = value;
    }


}


/***
 * 问题列表
 */
export class ChoiceQuestionList {
    questionList;   //问题列表


    constructor(questionList = []){
        this.questionList = questionList;
    }


    //获得符合约束条件的题目
    get passConditionOfQuestions(){
        return this.questionList.filter(function(question,index){
            return question.testAllCondition();
        });
    }

    //获得不符合约束条件的题目
    get notPassConditionOfQuestions(){
        return this.questionList.filter(function(question,index){
            return !(question.testAllCondition());
        });
    }


    //测试是否每一个题目都符合约束
    testEveryAccordCondition(){
        return this.questionList.every(function(question,index){
            return question.testAllCondition();
        });
    }


    //测试是否有部分题目符合约束
    testSomeAccordCondition(){
        return this.questionList.some(function(question,index){
            return question.testAllCondition();
        });
    }


    //测试是否每个题目都回答正确
    testEveryIsRight(){
        return this.questionList.every(function(question){
            return question.testAnswer();
        });
    }


    //测试是否部分题目回答正确
    testSomeIsRight(){
        return this.questionList.some(function(question){
            return question.testAnswer();
        });
    }


    //获得回答正确的题目
    get answerRightQuestions(){
        return this.questionList.filter(function(question){
            return question.testAnswer();
        });
    }


    //获得回答错误的题目
    get answerWrongQuestions(){
        return this.questionList.filter(function(question){
            return !(question.testAnswer());
        });
    }

    get totalScore(){
        return this.questionList.reduce(function(total,question){
            return total + question.totalScore;
        },0);
    }




}

